home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Leser 15 / Amiga Plus Leser CD 15.iso / Tools / Freeware / CharMap / Sources / helpwin.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-03-13  |  9.1 KB  |  303 lines

  1. /***********************************************************
  2. ** helpwin.c: Display a little help window of a character **
  3. **            Ã‰crit par T.Pierron                         **
  4. **            15-03-1999                                  **
  5. ***********************************************************/
  6.  
  7. #include <intuition/intuition.h>
  8. #include <graphics/rastport.h>
  9. #include <graphics/text.h>
  10. #include <exec/memory.h>
  11. #include <devices/keymap.h>
  12.  
  13. #include    "cmap.h"
  14. #define    CATCOMP_NUMBERS
  15. #define    CATCOMP_STRINGS
  16. #include    "cmap_strings.h"
  17.  
  18. extern struct RastPort *RP,RPT;
  19. extern struct Screen   *screen;
  20.  
  21. /*** Measure the maximal lenght of a NULL-terminated array of string: ***/
  22. WORD Meas_table(UBYTE **strings)
  23. {
  24.     register UBYTE **p;
  25.     register WORD  maxlen,len;
  26.  
  27.     for(p=strings, maxlen=0; *p; p++)
  28.         if(maxlen < (len=TextLength(&RPT,*p,strlen(*p)))) maxlen = len;
  29.  
  30.     return maxlen;
  31. }
  32.  
  33. TEXT *Qualifier[]={ "ctrl ","shift ","alt " },Str[50];
  34.  
  35. /*** Put description of keystroke for character into buffer    ****
  36. **** Original source code taken from FontViewQ by Dieter Temme ****
  37. **** Tanks for its great work! Code remains almost unchanged   ***/
  38. void GoodMapANSI(UBYTE chr, TEXT *buffer)
  39. {
  40.     /* >> these definitions are hopefully ok in all national keymaps! << */
  41.     #define NUMDEADKEYS 5                        /* a maximum of 16 is possible */
  42.     static TEXT deadkeys[NUMDEADKEYS]=        /* rawkey codes of deadkeys */
  43.     { 0x23, 0x24, 0x25, 0x26, 0x27 };
  44.  
  45.     struct KeyMap *km=(void *) AskKeyMapDefault(); /* pointer to default keymap */
  46.     UBYTE qualflags;                                /* qualifiers SHIFT, ALT, CTRL */
  47.     UBYTE key;                                        /* raw key number 0x00 .. 0x7f */
  48.     UBYTE dead= 0;                                    /* number of deadkey from table */
  49.  
  50.     static const UBYTE mapoffsets[8][8] =    /* [LoKeyMapTypes[lokey]][qualflags] */
  51.     {    /*  none,   S,    A,   SA,    C,   SC,   AC,  SAC */
  52.         {    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff    },    /* none */
  53.         {    0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff    },    /* S    */
  54.         {    0x00, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff    },    /*  A   */
  55.         {    0x00, 0x01, 0x02, 0x03, 0xff, 0xff, 0xff, 0xff    },    /* SA   */
  56.         {    0x00, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff    },    /*   C  */
  57.         {    0x00, 0x01, 0xff, 0xff, 0x02, 0x03, 0xff, 0xff    },    /* S C  */
  58.         {    0x00, 0xff, 0x01, 0xff, 0x02, 0xff, 0x03, 0xff    },    /*  AC  */
  59.         {    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07    }    /* SAC  */
  60.     };
  61.  
  62.     buffer[0]= '\0';
  63.  
  64.     /*- get control characters using the common way -*/
  65.     if ((chr&0x7f) < ' ')
  66.     {    union
  67.         {    UWORD word;
  68.             struct
  69.             {    UBYTE code, qual;
  70.             } bytes;
  71.         } buf;
  72.  
  73.         if (MapANSI(&chr, 1, &buf, 1, NULL) > 0)
  74.         {    key= buf.bytes.code;
  75.             qualflags= 0;
  76.             if (buf.bytes.qual&(IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  77.                 qualflags|= KCF_SHIFT;
  78.             if (buf.bytes.qual&(IEQUALIFIER_LALT|IEQUALIFIER_RALT))
  79.                 qualflags|= KCF_ALT;
  80.             if (buf.bytes.qual&(IEQUALIFIER_CONTROL))
  81.                 qualflags|= KCF_CONTROL;
  82.             goto found;
  83.         }
  84.     }
  85.  
  86.     /*- find rawkey qualifier and code in keymap -*/
  87.     {    BYTE offset;                /* byte offset into LoKeyMap[lokey] */
  88.         BOOL deadflag;                /* FALSE: search non-dead, TRUE: dead */
  89.         UBYTE *kmtypes;            /* pointer into km_??KeyMapTypes */
  90.         ULONG *kmmap;                /* pointer into km_??KeyMap */
  91.  
  92.         /*- sorry, original MapANSI, is a little bit broken, whereas this one works... -*/
  93.         for (deadflag= FALSE; deadflag <= TRUE; deadflag++)
  94.         {    for (qualflags= KC_NOQUAL; qualflags <= KC_VANILLA; qualflags++)
  95.             {    for (key= 0; key <= 0x78; key++)
  96.                 {    if (!(key&0x3f))
  97.                     {    kmtypes= key&0x40?
  98.                             km->km_HiKeyMapTypes : km->km_LoKeyMapTypes;
  99.                         kmmap= key&0x40? km->km_HiKeyMap: km->km_LoKeyMap;
  100.                     }
  101.                     offset= mapoffsets[*kmtypes&KC_VANILLA][qualflags];
  102.                     if (!(*kmtypes&KCF_NOP) && (offset >= 0))
  103.                     {    if (*kmtypes&KCF_DEAD)
  104.                         {    UBYTE *addr= (UBYTE *)*kmmap;
  105.                             if (addr[offset<<1]&DPF_MOD)
  106.                             {    addr+= addr[(offset<<1)|1]+deadflag;
  107.                                 dead= deadflag;
  108.                                 do
  109.                                 {    if (*addr == chr) goto found;
  110.                                     addr++;
  111.                                     dead++;
  112.                                 } while (deadflag && (dead != NUMDEADKEYS+1));
  113.                                 dead= 0;
  114.                             } else if (((UWORD *)addr)[offset] == (UWORD)chr)
  115.                                 goto found;
  116.                         } else if (!deadflag && !(offset&4))
  117.                         {    offset= (offset&3)^3;
  118.                             if (*kmtypes&KCF_STRING)
  119.                             {    UBYTE *addr= (UBYTE *)*kmmap;
  120.                                 if ((addr[offset<<1] == 1)
  121.                                     && (addr[addr[(offset<<1)|1]] == chr))
  122.                                     goto found;
  123.                             } else if (((UBYTE *)kmmap)[offset] == chr)
  124.                                 goto found;
  125.                         }
  126.                     }
  127.                     kmtypes++;
  128.                     kmmap++;
  129.                 }
  130.             }
  131.         }
  132.     }
  133.     return; /* not found */
  134.  
  135. found:
  136.     /*- put description into buffer -*/
  137.     {    struct InputEvent ie;            /* structure for MapRawKey() */
  138.         TEXT *index;                        /* temporary index for highkeys */
  139.  
  140.         static UBYTE highkeycodes[]=
  141.         {    0x40,        0x48,        0x50,        0x58,
  142.             0x41,        0x49,        0x51,        0x59,
  143.             0x42,                    0x52,        0x5f,
  144.             0x43,        0x4b,        0x53,
  145.             0x44,        0x4c,        0x54,        0x6e,
  146.             0x45,        0x4d,        0x55,        0x6f,
  147.             0x46,        0x4e,        0x56,        0x70,
  148.             0x47,        0x4f,        0x57,        0x71,        0
  149.         };
  150.         /*- corresponding key names of previous rawkey codes -*/
  151.         static TEXT *highkeytexts[]=
  152.         {    "space",            "page up",        "f1",    "f9",
  153.             "backspace",    "page down",    "f2",    "f10",
  154.             "tab",                                "f3",    "help",
  155.             "enter",            "f11",            "f4",
  156.             "return",        "up",                "f5",    "pause",
  157.             "esc",            "down",            "f6",    "f12",
  158.             "del",            "right",            "f7",    "home",
  159.             "insert",        "left",            "f8",    "end"
  160.         };
  161.         static TEXT numkeycodes[]=
  162.         {    0x0f, 0x1d, 0x1e, 0x1f, 0x2d, 0x2e, 0x2f, 0x3c,
  163.             0x3d, 0x3e, 0x3f, 0x4a, 0x5a, 0x5b, 0x5c, 0x5d,
  164.             0x5e, 0
  165.         };
  166.  
  167.         ie.ie_Class= IECLASS_RAWKEY;
  168.         ie.ie_Qualifier= 0;
  169.         ie.ie_EventAddress= 0;
  170.  
  171.         /*- dead key need to be pushed before -*/
  172.         if (dead)
  173.         {    strcpy(buffer, "alt  , ");
  174.             ie.ie_Code=deadkeys[dead-1];
  175.             MapRawKey(&ie, buffer+4, 1, km);
  176.         }
  177.  
  178.         if (qualflags&KCF_CONTROL)    strcat(buffer, Qualifier[0]);
  179.         if (qualflags&KCF_SHIFT)    strcat(buffer, Qualifier[1]);
  180.         if (qualflags&KCF_ALT)        strcat(buffer, Qualifier[2]);
  181.  
  182.         if (key && (index = (TEXT *) strchr(highkeycodes, key)))
  183.             strcat(buffer, highkeytexts[index-highkeycodes]);
  184.         else
  185.         {    if (key && strchr(numkeycodes, key)) strcat(buffer, "nk ");
  186.             strcat(buffer," "); ie.ie_Code= key;
  187.             MapRawKey(&ie, strrchr(buffer, ' '), 1, km);
  188.         }
  189.     }
  190. }
  191.  
  192.  
  193. #define    NBPOPMSG                (sizeof(popmsg)/sizeof(popmsg[0])-1)
  194.  
  195. extern UBYTE MaxWid;
  196. extern WORD txtpen,poppen,shine,darkpen;
  197. UBYTE *popmsg[]={ MSG_CODE_STR,MSG_DEC_STR,MSG_HEX_STR,MSG_OCT_STR,0 },Digits[]="0999";
  198. WORD   Xp[NBPOPMSG+1], Yp, DgtW, MaxX, MaxY, MaxMsg;
  199.  
  200. /*** Init width and height of our help window: ***/
  201. void Init_helpwin( struct Window *Wnd )
  202. {
  203.     UBYTE I, **msg;
  204.     SetFont(&RPT, screen->RastPort.Font);
  205.     SetFont(RP = Wnd->RPort, RPT.Font);
  206.  
  207.     /** Compute some text width **/
  208.     MaxX = Wnd->Width-Wnd->BorderRight-1;
  209.     MaxY = Wnd->Height-Wnd->BorderBottom-1;
  210.     DgtW = TextLength(&RPT,Digits,sizeof(Digits)-1)+5;
  211.     Yp   = MaxY-RPT.Font->tf_YSize;
  212.     for(MaxMsg=1, msg=popmsg, Xp[0]=10; MaxMsg <= NBPOPMSG; MaxMsg++, msg++)
  213.         /* Be sure keystroke can be entirely visible */
  214.         if( (Xp[ MaxMsg ] = TextLength(&RPT,*msg,strlen(*msg)) + Xp[MaxMsg-1] + (MaxMsg==1 ? MaxWid : DgtW) + 5) > MaxX-120 )
  215.             break;
  216.     MaxMsg--;
  217.  
  218.     /** Draws shape of information box **/
  219.     SetAPen(RP,darkpen);
  220.     Move(RP, Wnd->BorderLeft, Yp-5);
  221.     Draw(RP, MaxX, RP->cp_y);
  222.     SetAPen(RP,shine);
  223.     Move(RP, RP->cp_x, RP->cp_y+1);
  224.     Draw(RP, Wnd->BorderLeft, RP->cp_y);
  225.     SetAPen(RP,poppen);
  226.     RectFill(RP, RP->cp_x, RP->cp_y+1, MaxX, MaxY);
  227.  
  228.     /** Draws some text **/
  229.     SetAPen(RP,shine); SetDrMd(RP,JAM1); Yp += RPT.Font->tf_Baseline;
  230.     for(I=0,msg=popmsg; I<MaxMsg; I++,msg++)
  231.         Move(RP,Xp[I],Yp),Text(RP,*msg,strlen(*msg));
  232.  
  233.     /** Vertical rule **/
  234.     SetAPen(RP,darkpen);
  235.     Move(RP, Xp[I], MaxY);
  236.     Draw(RP, RP->cp_x, Yp-RPT.Font->tf_Baseline-5);
  237.     SetAPen(RP,shine);
  238.     Move(RP, RP->cp_x+1, RP->cp_y+1);
  239.     Draw(RP, RP->cp_x, MaxY);
  240. }
  241.  
  242. /*** Convert bin to Base ***/
  243. void convert_to_base(UBYTE *Str,UBYTE Var,BYTE Base)
  244. {
  245.     UBYTE ChConv[]="0123456789abcdef";
  246.     UBYTE *ptr=Str,L=0;
  247.  
  248.     do {
  249.         L++;
  250.         *ptr-- = ChConv[ Var%Base ];
  251.     } while(Var /= Base);
  252.  
  253.     switch( Base )
  254.     {
  255.         case 16: *ptr--='x'; L++;
  256.         case 8:  *ptr--='0'; L++;
  257.     }
  258.     Text(RP,ptr+1,L);
  259. }
  260.  
  261. /*** Display information in the window: ***/
  262. void Disp_charinfo( UBYTE Num )
  263. {
  264.     struct TextFont *Old;
  265.     int i, CharLen;
  266.  
  267.     Old = RP->Font;
  268.     SetFont(RP,screen->RastPort.Font);
  269.     SetAPen(RP,poppen); SetBPen(RP,poppen); SetDrMd(RP,JAM2);
  270.     /* Code of character (maybe larger than believed) */
  271.     CharLen = TextLength(RP,&Num,1);
  272.     RectFill(RP, Xp[1]-MaxWid-2, Yp-RP->Font->tf_Baseline, Xp[1]-1, MaxY);
  273.     if(CharLen <= MaxWid)
  274.         SetAPen(RP, shine), Move(RP,Xp[1]-2-(MaxWid+CharLen>>1),Yp), Text(RP,&Num,1);
  275.  
  276.     for(i=2; i<=MaxMsg; i++)
  277.     {
  278.         /* Clears old text before */
  279.         SetAPen(RP,shine);
  280.         Move(RP,Xp[i] - DgtW,Yp);
  281.         convert_to_base(Str+6,Num,i==2? 10 : i==3? 16 : 8);
  282.  
  283.         SetAPen(RP,poppen);
  284.         RectFill(RP, RP->cp_x, RP->cp_y - RP->Font->tf_Baseline, Xp[i]-1, MaxY);
  285.     }
  286.     /* Display the keystroke of this char */
  287.     GoodMapANSI(Num, Str);
  288.     Move(RP,Xp[MaxMsg]+7,Yp);
  289.     SetAPen(RP,poppen); SetDrMd(RP,JAM1);
  290.     RectFill(RP,RP->cp_x-4,RP->cp_y-RP->Font->tf_Baseline,MaxX,MaxY);
  291.     SetAPen(RP,shine); 
  292.     if( *Str ) Text(RP,Str,strlen(Str));
  293.     if( *Str == 0 )
  294.     {
  295.         /* Keystroke hasn't been found, print msg in italic to **
  296.         ** enlighten that it is not a keystroke sequence       */
  297.         RP->AlgoStyle = FSF_ITALIC; SetAPen(RP,shine);
  298.         Text(RP,ErrMsg(MSG_KSNOTFOUND),strlen(ErrMsg(MSG_KSNOTFOUND)));
  299.         RP->AlgoStyle = FS_NORMAL;
  300.     }
  301.     SetFont(RP,Old);
  302. }
  303.